package org.example.blockchain;

import org.example.transaction.Transaction;
import org.example.transaction.TransactionInput;
import org.example.utils.StringUtils;

import java.util.ArrayList;
import java.util.Date;

public class Block {
    public String hash;
    public String prevHash;
    public String merkleRoot;
    public ArrayList<Transaction> transactions = new ArrayList<Transaction>();
//    private String data;
    public long timestamp;
    public int nonce;

    public Block(String prevHash) {
        this.prevHash = prevHash;
        this.timestamp = new Date().getTime();
        this.hash = calculateHash();
    }

    public String calculateHash() {
        String calculatehash = StringUtils.applySha256(prevHash
                + Long.toString(timestamp)
                + Integer.toString(nonce)
                + merkleRoot);
        return calculatehash;
    }

    public void mineBlock(int difficulty) {
//        String target = new String(new char[difficulty]).replace('\0', '0');
//        System.out.println("Target : " + target);
        merkleRoot = StringUtils.getMerKleRoot(transactions);
        String target = StringUtils.getDifficultyString(difficulty);
        while(!hash.substring(0, difficulty).equals(target)) {
//            System.out.println("value : " + hash.substring(0, difficulty));

            nonce++;
            hash = calculateHash();
        }
        System.out.println("Block Mined! : " + hash);
    }

    public boolean addTransaction(Transaction transaction) {
        if (transaction == null) {
            return false;
        }

        if(prevHash != "0") {
            if(transaction.processTransaction() != true) {
                System.out.println("Transaction failed to process. Discarded.");
                return false;
            }
        }
        transactions.add(transaction);
        System.out.println("Transaction successfully added to block.");
        return true;
    }

}
